
<script>
import { start, close, info } from 'services/x-start/mgr/device'
import ip from 'ip'
import qs from 'qs'
let ispord = process.env.NODE_ENV == 'production'

export default {
  props: {
    url: {
      type: String,
      default: 'rtmp://isxsports.com/dext/live14',
    },
    id: {
      type: String,
      default: 'my-video',
    },
    line: {
      type: String,
      default: '',
    },
    visible: Boolean,
    isShowLine: {
      type: Boolean,
      default: true,
    },
    title: {
      type: String,
      default: '划线设置',
    },
    isCanLine: {
      type: Boolean,
      default: true,
    },
    item: {
      type: Object,
      default: {},
    },
  },
  data() {
    return {
      myPlayer: null,
      lineBox: false,
      isRtsp: null,
      loading: false,
      file: null,
      canvas: null,
      timer: null,
      info: null,
      isClose: false,
      urlType: null,
      getInfoType: true,
    }
  },
  created() {
    this.isRtsp = /^rtsp:/.test(this.url)
    if (this.url && (/^http:/.test(this.url) || /^https:/.test(this.url))) {
      this.urlType = this.url.substr(this.url.lastIndexOf('.') + 1)
    } else {
      this.urlType = this.url.substr(0, this.url.indexOf('://'))
    }
  },
  mounted() {
    console.log(this.urlType)
    switch (this.urlType) {
      case 'm3u8':
        this.playM3u8()
        break
      case 'rtsp':
        this.playRtsp()
        break
      case 'rtmp':
        this.playRtmp()
        break
      default:
        this.getInfoType = false
        this.$message.warning('缺少对应格式')
        break
    }
    if (this.item.id && this.getInfoType) {
      // this.getInfo()
    }
    window.addEventListener('beforeunload', (e) => this.beforeunloadHandler(e))
  },
  computed: {
    rtspUrl() {
      if (!process.env.VUE_APP_RTSP_URL) {
        return ip.address()
      }
      return process.env.VUE_APP_RTSP_URL.replace('http://', '').replace(
        ':8088',
        ''
      )
    },
  },
  methods: {
    beforeunloadHandler(e) {
      this.close()
    },
    close(type) {
      if (!this.isClose && this.isRtsp) {
        close({ url: this.url }).catch(({ payload }) => {
          console.log(payload.message)
        })
      }
      clearTimeout(this.timer)
      try {
        if (this.isRtsp) {
          this.myPlayer.destroy()
        } else {
          this.myPlayer.dispose()
        }
        this.myPlayer = null
      } catch (error) {}
      this.$emit('update:visible', false)
    },
    save() {
      let lineInfo = this.$refs.videoLine
      let baseWidth = lineInfo.canvas.width
      let baseHeight = lineInfo.canvas.height
      let start = lineInfo.start
      let end = lineInfo.end
      if (!start.x || !end.x) {
        this.$message.warning('请在红框内划线')
        return
      }
      this.drawCanvas()
        .then((res) => {
          console.log(this.file)
          let coordinate = `[{"x":${(start.x / baseWidth).toFixed(2)},"y":${(
            start.y / baseHeight
          ).toFixed(2)}},{"x":${(end.x / baseWidth).toFixed(2)},"y":${(
            end.y / baseHeight
          ).toFixed(2)}}]`
          this.close()
          this.$emit('saveCoordinate', { line: coordinate, file: this.file })
        })
        .catch((res) => {
          this.$message.error('图片合并失败')
        })
    },
    playRtsp() {
      start({ url: this.url })
        .then(({ port }) => {
          this.canvas = document.getElementById(this.id)
          let url = `ws://${this.rtspUrl}:${port}`
          this.myPlayer = new JSMpeg.Player(url, {
            canvas: this.canvas,
            preserveDrawingBuffer: true,
          })
          this.loading = this.lineBox = true
        })
        .catch(({ payload }) => {
          this.$message.error(
            payload ? payload.message : '启动本地解码功能失败！'
          )
          this.isClose = true
          this.close()
        })
    },
    playRtmp() {
      setTimeout(() => {
        this.myPlayer = videojs(this.id, { autoplay: true })
        this.myPlayer.ready(() => {
          setTimeout(() => {
            this.myPlayer.pause()
            this.myPlayer.play()
            this.lineBox = this.loading = true
          }, 500)
        })
      }, 20)
    },
    playM3u8() {
      this.$nextTick(() => {
        let video = document.getElementById('video')
        if (Hls.isSupported()) {
          let hls = new Hls()
          hls.loadSource(this.url)
          hls.attachMedia(video)
          hls.on(Hls.Events.MANIFEST_PARSED, () => {
            video.play()
          })
        }
      })
      // this.$nextTick(() => {
      //   videojs(
      //     this.id,
      //     {
      //       autoplay: true,
      //       bigPlayButton: true,
      //       textTrackDisplay: false,
      //       posterImage: false,
      //       errorDisplay: false,
      //     },
      //     function () {
      //       this.play()
      //     }
      //   )
      // })
    },
    dataURLtoBlob(dataurl) {
      let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], { type: mime })
    },
    drawCanvas() {
      if (!this.isRtsp) {
        return html2canvas(document.getElementById('my-video'), {
          width: 660,
          height: 400,
          allowTaint: true,
          useCORS: true,
        }).then((canvas) => {
          this.canvas = canvas
          return this.drawingCanvas()
        })
      } else {
        return this.drawingCanvas()
      }
    },
    drawingCanvas() {
      let imgsrcArray = [
        this.canvas.toDataURL(), //视频内容
        this.$refs.videoLine.canvas.toDataURL(), //划线内容
      ]
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      canvas.width = 660
      canvas.height = 400
      let imglen = imgsrcArray.length
      let pr = []
      return new Promise((resolve, reject) => {
        imgsrcArray.forEach((url) => {
          let p = this.loadImage(url)
            .then((img) => {
              return ctx.drawImage(img, 0, 0, 660, 400)
            })
            .catch((err) => console.log(err))
          pr.push(p)
        })
        Promise.all(pr).then(() => {
          this.file = this.dataURLtoBlob(canvas.toDataURL('image/jpeg'))
          resolve(true)
        })
      })
    },
    loadImage(url) {
      return new Promise((resolve, reject) => {
        let img = new Image()
        img.onload = () => resolve(img)
        img.onerror = reject
        img.src = url
      })
    },
    getInfo() {
      info({ id: this.item.id })
        .then((res) => {
          this.info = res.data
          if (res.data != null) {
            this.timer = setTimeout(() => {
              this.getInfo()
            }, 1000)
          }
        })
        .catch((res) => {
          console.log('链接失败')
        })
    },
  },
  destroyed() {
    window.removeEventListener('beforeunload', (e) =>
      this.beforeunloadHandler(e)
    )
  },
}
</script>

<template lang="pug">
el-dialog.restBody2(
  :center='false',
  width='700px',
  top='50px',
  :visible.sync='visible',
  :close-on-click-modal='false',
  :close-on-press-escape='false',
  :before-close='close',
  append-to-body,
  :title='title'
)
  .video(
    ref='video',
    v-loading='!loading',
    element-loading-text='视频启动中...',
    element-loading-spinner='el-icon-loading',
    element-loading-background='rgba(0, 0, 0, 0.8)'
  )
    canvas.rtspCanvas(
      :id='id',
      v-if='urlType == "rtsp"',
      width='600',
      height='400'
    )
    video#video.video(v-show='urlType == "m3u8"')
      //- v-if='urlType == "rtmp" || urlType == "m3u8"',
    video.video-js(
      v-if='urlType == "rtmp"',
      :id='id',
      ref='videojs',
      controls,
      autoplay='true',
      preload='auto',
      width='660px',
      data-setup='{}'
    )
      source#source(
        :src='url || "rtmp://isxsports.com/dext/live14"',
        type='application/x-mpegURL'
      )
    videoLine(
      v-if='lineBox',
      ref='videoLine',
      :line='line',
      :isCanLine='isCanLine'
    )
    //- template(v-if='loading')
    //-   ul.info(v-if='info')
    //-     li 进入人数：{{ info.ent }}
    //-     li 离开人数：{{ info.ext }}
    //-     li 当前人数：{{ info.person }}
    //-   p.info(v-else) 视频未启动或已中断
  .dialog-footer(slot='footer')
    el-button(type='info', size='small', @click='close') 取消
    el-button(type='primary', size='small', @click='save', v-if='isShowLine') 确定
</template>

<style lang="stylus" scoped>
.info
  background rgba(0, 0, 0, 0.5)
  color #fff
  padding 15px
  display flex
  position absolute
  width 100%
  box-sizing border-box
  bottom 0
  li
    margin-right 20px
.video
  width 100%
  display inline-block
  border 2px solid red
  position relative
  background #000
  .rtspCanvas
    margin 0 auto
    display block
  .canvas
    position absolute
    top 0
    left 0
  .video-js
    width 100%
</style>
